/*
 * string.c - Mokri
 * Contributors: xMine
 * (Any new Contributor may add himself/herself to the list)
 * Changes and fixes to be made:
 */

#include "string.h"

/* Gibt die Länge eines Strings zurück
 * Parameter: char-Array
 * Rückgaben: Stringlänge
 */
int strlen (const char *str) {
	int i = 0;
	while (str[i]) {
		i++;
	}

	return i;
}

char *strcpy (char *dst, const char *src) {
//	memset (dst, 0x0, strlen(src)+1);
	return memcpy (dst, src, strlen (src));
}

char *strcat (char *dst, const char *src) {
	return memcpy (dst+strlen(dst), src, strlen(src));
}

BOOL _strcmp (const char *str1, const char *str2) {
	int i, len = strlen (str1);
	if (len != strlen(str2)) { // Länge gleich?
		return FALSE;
	}

	for (i=0; i<len; i++) {
		if (str1[i] != str2[i]) {
			return FALSE;
		}
	}

	return TRUE;
}

char *strstr (const char *str1, const char *str2) {
	int i,j;
	int l1 = strlen (str1);
	int l2 = strlen (str2);

	if (l2 > l1) { // Wenn str2 länger ist als str1 abbrechen
		return NULL;
	}

	for (i=0; i<l1; i++) {
		for (j=0; j<l2; j++) {
			if (str1[i+j] != str2[j]) {
				break;
			}
		}

		if (j == l2) {
			return (char*)(str1+i);
		}
	}

	return NULL;
}

/* Sucht nach einem einzelnen Zeichen
 * Parameter: Suchstring, das gesuchte Zeichen
 * Rückgaben: Bei Fund einen Pointer der auf den Fundort zeigt, ansonsten NULL
 */
char *strchr (char *str, int charachter) {
	char *ptr = str;
	char c = (char)charachter;
	
	while (*ptr != 0x0) {
		if (*ptr == c) {
			return ptr;
		}
		
		ptr++;
	}
	
	return NULL;
}

/* Sucht nach einem einzelnen Zeichen in einem Bereich
* Parameter: Suchstring, Bereich anfang, Bereich ende
* Rückgaben: Bei Fund einen Pointer der auf den Fundort zeigt, ansonsten NULL
*/
char *strfind (char *str, char start, char ende) {
	char *ptr = str;
	
	while (*ptr != 0x0) {
		if (*ptr >= start && *ptr <= ende) {
			return ptr;
		}
		
		ptr++;
	}
	
	return NULL;
}

/* Spaltet einen String
 * Parameter: Zeiger auf einen char-Array, Zeiger auf einen integer (enthält nach dem Aufruf die Anzahl der Elemente)
 * Rückgaben: Zeiger auf einen char**
 */
char **strsplit (const char *str, int *elements) {
	char *ret = (char*)malloc (strlen(str)+1);
	char **arr;
	int i, j;
	*elements = 1;
	
	memcpy (ret, str, strlen(str)+1);
	
	for (i=0; str[i]; i++) {
		if (str[i] == ' ') {
			elements[0]++;
		}
	}
	
	if (elements[0] < 2) {
		*elements = 1;
		arr = (char**)malloc (4);
		arr[0] = ret;
		return arr;
	}
	
	j = 1;
	arr = (char**)malloc ( (elements[0])*4 );
	arr[0] = ret;
	
	for (i=0; j<elements[0]; i++) {
		if (ret[i] == ' ') {
			arr[j] = (char*)(ret+i+1);
			ret[i] = 0x0;
			j++;
		}
	}
	
	return arr;
}

char * fill (char filler, int anzahl, char *buf) {
	int i;
	for (i=0; i<anzahl; i++) {
		buf[i] = filler;
	}
	
	buf[i] = 0x0;
	return buf;
}

void dump_hex (void *input, int len) {
	int i;
	char *str;
	char human[34];
	char fillstr[81];
	char tmp;
	char col;
	char *data = input;
	int b;
	memset (human, 0x0, 34);
	
	fill (' ', 80, fillstr);
	
	printf ("=== HEX AUSGABE VON 0x%p LEN: %i ===", data, len);
	for (i=0; i<len; i++) {
		if (i % 16 == 0) {
			b = 0;
			printf ("%s%c\n%c0x%07x: ", human, (char)21, (char)18, i);
			memset (human, 0x0, 17);
		} else if (i % 4 == 0) {
			print (" ");
			b++;
		}
		
		str = uint2str ((uint32_t)((uint8_t)(*(data+i))), 16);
		if (strlen (str) < 2) {
			print ("0");
			b++;
		}
		
		col = 23;
		tmp = (uint8_t)(*(data+i)); // Für die ASCII Ausgabe
		if ( !(tmp >= ' ' && tmp <= '~') ) { // Ist das Zeichen Druckbar?
			col = 16;
			tmp = '.';
		}
		
		human [(i%16)*2] = col; // Farbe
		human [(i%16)*2+1] = tmp; // Zeichen
		
		b += strlen (str) + 1;
		
		printf ("%s ", str);
		free (str);
	}
	
	fillstr [51-b] = 0x0; // Damit wird die ASCII Ausgabe rechts orientiert ausgegeben
	printf ("%s%s\n", fillstr, human);
}
